package com.vectz.mgt.action;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.print.attribute.standard.MediaSize.NA;

import com.vectz.mgt.model.Entity;
import com.vectz.mgt.model.EntityOverview;
import com.vectz.mgt.util.Constant;
import com.vectz.mgt.util.Log;
import com.vectz.mgt.util.Util;

/**
 * @author ai-t.vn
 * 
 */
public class ActionCodegenAction {
	ArrayList<Entity> listField = null;
	EntityOverview table = null;
	String outputFolder = "";
	int numFileUpload = 0;
	String downloadFileName = "download.xls";
	
	private Hashtable<String, String> fieldFileUploadSet = new Hashtable<String, String>();
	private Hashtable<String, String> fieldFileUploadGet = new Hashtable<String, String>();
	
	public ActionCodegenAction(ArrayList<Entity> listField,
			EntityOverview table, String outputFolder)  throws Exception {
		this.listField = listField;
		this.table = table;
		this.outputFolder = outputFolder;
		genernateActionFile();
	}

	/*
	 * Generate java action file
	 */
	public void genernateActionFile() throws Exception  {
			String tmplFormContent = Util.readTextFileContent(Util.getTmplPath(
					"action", "Action-File.txt"));

			tmplFormContent = tmplFormContent.replaceAll("xxxxPackageName",
					table.getPackageName());
			tmplFormContent = tmplFormContent.replaceAll("xxxxActionName", Util
					.lowerCaseFirstChar(table.getName())
					+ "Action");
		
			tmplFormContent = tmplFormContent.replaceAll("xxxxEntity", table
					.getName());
			tmplFormContent = tmplFormContent.replaceAll("xxxxLEntity", Util
					.lowerCaseFirstChar(table.getName()));
			tmplFormContent = tmplFormContent.replaceAll("xxxxPkType", Util
					.getPKType(listField));
			tmplFormContent = tmplFormContent.replaceAll("xxxxInitNew", Util
					.buildButtonAction(table.getName(), "initNew"));
			
			numFileUpload = getNumFileUpload(); 
			//replace define of file upload
			tmplFormContent = tmplFormContent.replaceAll("xxxxFileUploadDefine",generateFileUploadDefine());
			//replace file upload method
			tmplFormContent = tmplFormContent.replaceAll("xxxxFileUploadMethod",generateFileUploadMethod());
			//replace action in initNew() method
			tmplFormContent = tmplFormContent.replaceAll("xxxxInitFileUploadNew",generateInitFileUploadNew());
			//replace action in initModify() and delete() method
			tmplFormContent = tmplFormContent.replaceAll("xxxxInitFileUploadModify",generateInitFileUploadModify());
			//replace action in confirm() method
			tmplFormContent = tmplFormContent.replaceAll("xxxxFileUploadAdd",generateFileUploadAdd());
			//replace action in donwload() method
			tmplFormContent = tmplFormContent.replaceAll("xxxxDownloadAction",generateDownloadMethod());
			
			if (listField != null) {
				Entity field = null;
				String datetimeField = "";
				boolean isFileUpload = false;
				for (int i = 0; i < listField.size(); i++) {
					field = (Entity) listField.get(i);
					if (field != null) {
					
						if ( field.getInputDataType()!=null 
								&& field.getInputDataType().equalsIgnoreCase("VECDATETIME")) {
							datetimeField += new StringBuffer()
							.append(Util.lowerCaseFirstChar(table.getName())+".set"+Util.upperCaseFirstChar(field.getName())+"(new ")
							.append(Util.dbTypeToJavaType(field.getInputDataType())+"());\n")
							.toString();
						}
					}
					if(!Util.isEmpty(datetimeField)){
						String ifStatement = "if(" +Util.lowerCaseFirstChar(table.getName())+".get"
									+Util.upperCaseFirstChar(field.getName())+"()==null){\n\t"
									+datetimeField+"}\n";
						tmplFormContent = tmplFormContent.replaceAll("xxxxInitData",ifStatement);
						datetimeField = "";
					}
					
				}
				
				if(!isFileUpload)
					tmplFormContent = tmplFormContent.replaceAll("xxxxDownloadAction","");
				
			}
			tmplFormContent = tmplFormContent.replaceAll("xxxxInitData", "");
			String fileLocation = new StringBuffer().append(outputFolder)
					.append(System.getProperty("file.separator")).append("src")
					.append(System.getProperty("file.separator")).append(
							"action").append(
							System.getProperty("file.separator")).append(
							table.getName()).append("Action.java").toString();

			Util.writeJsfFile(fileLocation, tmplFormContent);
			Log.log("Finish generate java file to:" + fileLocation);

	}
	
	/**
	 * generate fileUpload define 
	 * 
	 * @return
	 */
	public String generateFileUploadDefine(){
		String fileUploadDefine = "";
		StringBuffer tmp = new StringBuffer();
		if(numFileUpload!= 0){
			for (int i = 1; i <= numFileUpload; i++) {
				//file upload
				tmp = tmp
					.append("private String fileName"+i+";\n");
			}
			//hash of file name, hash of file data, index file download
			tmp.append("private Hashtable<String, String> fileName = new Hashtable<String, String>();\n")
				.append("private Hashtable<String, byte[]> fileData = new Hashtable<String, byte[]>();\n")
				.append("private Hashtable<String, byte[]> fileDataModify = new Hashtable<String, byte[]>();\n")
				.append("@RequestParameter \n")
				.append("private String index=\"\";\n\n");

			fileUploadDefine = tmp.toString();
			
		}
		return fileUploadDefine;
	}
	
	/**
	 * generate fileUpload method 
	 * 
	 * @return
	 */
	public String generateFileUploadMethod(){
		String fileUploadMethod = "";
		StringBuffer tmp = new StringBuffer();
		if(numFileUpload!= 0){
			for (int i = 1; i <= numFileUpload; i++) {
				//file upload
				tmp = tmp
					.append("public void setFileName"+ i+"(String fileName) {\n")
					.append("this.fileName" + i+ " = fileName;\n")
					.append("}\n\n")
					.append("public String getFileName"+i+"() {\n")
					.append("return fileName"+i+";\n")
					.append("}\n\n");
			}
			//index of file download
			tmp.append("public void setIndex(String index){\n")
				.append("this.index = index;\n")
				.append("}\n\n")
				.append("public String getIndex(){\n")
				.append("return index;\n")
				.append("}\n\n");
			
			fileUploadMethod = tmp.toString();
		}
		return fileUploadMethod;
	}
	/**
	 * Generate init file upload data in  initModify() and delete() method
	 * 
	 * @return
	 */
	public String generateInitFileUploadModify(){
		String fileUploadNew = "";
		StringBuffer tmp = new StringBuffer();
		tmp.append("fileDataModify = new Hashtable<String, byte[]>();\n");
		tmp.append("fileData = new Hashtable<String, byte[]>();\n");
		tmp.append("fileName = new Hashtable<String, String>();\n");
		if(numFileUpload!= 0){
			for (int i = 1; i <= numFileUpload; i++) {
				//reset file name to ""
				tmp = tmp.append("fileName"+i +" = \"\";\n")
				.append("if("+ fieldFileUploadGet.get(String.valueOf(i))+".length != 0){\n")
				.append("fileName"+ i+" = \""+ downloadFileName+"\";\n")
				.append("fileDataModify.put(\""+ i+"\",")
				.append(fieldFileUploadGet.get(String.valueOf(i))+");\n}");
			}
			
			fileUploadNew = tmp.toString();
		}
		return fileUploadNew;
	}
	
	/**
	 * Generate init file upload data in initNew() method
	 * 
	 * @return
	 */
	public String generateInitFileUploadNew(){
		String fileUploadModify = "";
		StringBuffer tmp = new StringBuffer();
		tmp.append("fileDataModify = new Hashtable<String, byte[]>();\n");
		if(numFileUpload!= 0){
			for (int i = 1; i <= numFileUpload; i++) {
				//reset file name to ""
				tmp = tmp.append("fileName"+i +" = \"\";\n");
			}
			fileUploadModify = tmp.toString();
		}
		return fileUploadModify;
	}
	
	/**
	 * generate fileUpload action in confirm() method
	 * 
	 * @return
	 */
	public String generateFileUploadAdd(){
		String fileUploadAdd = "";
		StringBuffer tmp = new StringBuffer();
		if(numFileUpload!= 0){
			for (int i = 1; i <= numFileUpload; i++) {
				//set data and filename in case of edit entity
				tmp = tmp.append("if(fileName" + i +".equals(\"\") ")
				.append("&& fileDataModify.get(\""+i+"\")!=null")
				.append("&& fileDataModify.get(\""+i+"\").length !=0){\n")
				.append("fileName"+i+ "= \"" + downloadFileName+ "\";")
				.append(fieldFileUploadSet.get(String.valueOf(i))+"((byte[])fileDataModify.get(\""+i+"\"));\n")
				.append("}else if (!fileName"+ i+".equals(\"\")){\n")
				.append("fileName.put(\""+i+"\", fileName"+i+");\n")
				.append("fileData.put(\""+i+"\"," + fieldFileUploadGet.get(String.valueOf(i))+");\n}");
				
			}
			fileUploadAdd = tmp.toString();
		}
		return fileUploadAdd;
	}
	/**
	 * generate action in download() method
	 * 
	 * @return
	 */
	public String generateDownloadMethod(){
		String downloadMethod="";
		if(numFileUpload!= 0){
			downloadMethod  =  new StringBuffer()
					.append("if(fileName.get(index)!=null && !fileName.get(index).equals(\""+ downloadFileName+"\")){\n")
			 		.append("ByteArrayInputStream in = new ByteArrayInputStream((byte[])fileData.get(index));\n")
			 		.append("FileUtils.download(in, fileName.get(index).toString());\n")
			 		.append("} else {\n")
			 		.append("ByteArrayInputStream in = new ByteArrayInputStream((byte[])fileDataModify.get(index));\n")
			 		.append("FileUtils.download(in,\""+downloadFileName+"\");\n}").toString();
		}
		 return downloadMethod;
	}
	
	//return number fileUpload component
	public int getNumFileUpload(){
		int num = 0;
		if (listField != null) {
			Entity field = null;
			
			for (int i = 0; i < listField.size(); i++) {
				field = (Entity) listField.get(i);
				if (Util.dbTypeToJavaType(field.getInputDataType()).equalsIgnoreCase("byte[]")){
					num++;
					fieldFileUploadGet.put(String.valueOf(num),
							new StringBuilder()
							.append(Util.lowerCaseFirstChar(table.getName()))
							.append(".get")
							.append(Util.upperCaseFirstChar(field.getName()))
							.append("()").toString());
					fieldFileUploadSet.put(String.valueOf(num),
							new StringBuilder()
							.append(Util.lowerCaseFirstChar(table.getName()))
							.append(".set")
							.append(Util.upperCaseFirstChar(field.getName()))
							.toString());
				}
			}
		}
		return num;
	}

}
